MODOS
DE DIRECCIONAMIENTO FISICO Y VIRTUAL
No tiene mucho sentido que el propio sistema operativo
se ejecute sobre memoria
virtual. Sería una verdadera pesadilla que el sistema operativo
tuviera que mantener tablas de páginas para él
mismo. La mayoría de los procesadores de
propósito general ofrecen la posibilidad del modo de
direccionamiento físico junto con direccionamiento
virtual. El modo de direccionamiento físico no necesita
las tablas de páginas y el procesador no
intenta realizar ningún tipo de traduccines en este modo.
El núcleo de Linux está
preparado para funcionar sobre un espacio de direccionamiento
físico.
CONTROL DE ACCESO
Las entradas de la tabla de páginas
también contienen información relativa al control de
acceso. Puesto que el procesador tiene que utilizar la
información de la tabla de páginas para traducir
las direcciones virtuales a direcciones físicas, puede
fácilmente utilizar la información de control de
acceso para comprobar que el proceso no
está accediendo a memoria de forma
apropiada.
Hay muchas razones por las que se puede querer
restringir el acceso a determinadas áreas de memoria. Hay
memoria, como la que contiene el ejecutable, que es claramente
memoria de sólo lectura; el
sistema operativo no ha de dejar que el proceso escriba sobre su
propio código
de programa. Por
el contrario, páginas de memoria que contengan datos han de
poder ser
leídas y escritas, pero un intento de ejecutar algo de
estas páginas ha de fallar. La mayoría de los
procesadores tienen al menos dos modos de operación:
modo núcleo y modo usuario. No es deseable
que un proceso ejecute código del núcleo, o que
acceda a datos del núcleo excepto cuando el procesador
está funcionando en modo núcleo.
CACHES
Además de invertir esfuerzos en diseñar y
frabricar procesadores, memoria y otros dispositivos más
rápidos, mejor forma de obtener un buen rendimiento
consiste en mantener en memoria caches de la información
que se utiliza muy a menudo.
Linux emplea unas cuantas caches para la gestión
de la memoria,
entre las cuales tenemos:
Buffer Caché
Contiene buffers de datos que son utilizados por los
manejadores de dispositivos de bloques. Estos buffers son de
tamaño fijo (por ejemplo 512 bytes) y contienen bloques
de información que ha sido bien leída de un
dispositivo de bloques o que ha de ser escrita. Un dispositivo
de bloques es un dispositivo sobre el que sólo se pueden
realizar operaciones de
lectura o escritura de
bloques de tamaño fijo. Por ejemplo, los discos duros
son dispositivos de bloque. El cache buffer está
indexado vía el identificador de dispositivo y el
número de bloque deseado, índice que es utilizado
para una rápida localización del bloque. Los
dispositivos de bloque son exclusivamente accedidos a
través del buffer Cache.
Caché de Páginas
Este se utiliza para acelerar el acceso a imágenes
y datos en disco. Se utiliza para guardar el contenido
lógico de un fichero de página en página y
se accede vía el fichero y el desplazamiento dentro del
fichero. Conforme las páginas se leen en memoria, se
almacenan en la page caché..
Cache de Intercambio
Solo las páginas que han sido modificadas
(dirty) son guardadas en el fichero de intercambio.
Mientras no vuelvan a ser modificadas después de haber
sido guardadas en el fichero de swap, la próxima vez que
necesiten ser descartadas (swap out) no será necesario
copiarlas al fichero de intercambio pues ya están
allí.
Caches Hardware
Es una caché normalmente implementada en el
propio procesador; la cache de entradas de tabla de
página. En este caso, el procesador no necesita siempre
leer la tabla de páginas directamente, sino que guarda
en esta cache las traducciones de las páginas conforme
las va necesitando.
El inconveniente de utilizar memorias
cache, tanto hardware como
de otro tipo, es que para evitar esfuerzos Linux tiene que
utilizar más tiempo y
espacio para mantenerlas y, si se corrompe su contenido, el
sistema dejará de funcionar.
TABLA
DE PÁGINAS EN LINUX
Linux supone que hay tres niveles de tablas de
páginas:
- El directorio de tablas de páginas (punteros
a tablas intermedias). - La tabla de páginas intermedia (punteros a
tablas de páginas). - Las tablas de páginas (punteros a
páginas).
Cada plataforma sobre la que funciona Linux tiene que
proporcionar las macros que
permitan al núcleo atravesar las tablas de página
de cada proceso. De esta forma, el núcleo no necesita
conocer el formato de las entradas de la tabla de páginas
ni cómo éstas se organizan.
Esto es tan útil que Linux utiliza el mismo
código de gestión de tablas de páginas en un
procesador Alpha, que tiene tres niveles de tablas de
páginas, que en un Intel x86, que sólo tiene dos
niveles de tablas (para ello, supone que el tamaño de la
tabla intermedia es 1, y por tanto, coincide con la entrada del
directorio).
ASIGNACIÓN DE PÁGINAS
Linux utiliza el algoritmo
Buddy para asignar y liberar eficientemente bloques de
páginas. El código de asignación intenta
asignar un bloque de una o más páginas
físicas. Las páginas se asignan en bloques de
tamaño potencia de 2.
Esto quiere decir que pueden asignar bloques de 1, 2, 4, etc
páginas.
El algoritmo de asignación busca primero entre
los bloques de páginas de igual tamaño que el
pedido. Luego sigue la lista de páginas libres que
está encolada. Si no encuentra ningún bloque de
páginas del tamaño pedido libre, entonces busca en
los siguientes (los cuales son del doble del tamaño
pedido).
Puesto que el número de páginas de cada
bloque es potencia de 2, simplemente dividiendo el bloque por la
mitad se obtienen dos bloques con un tamaño de bloque
inmediatamente inferior.
LIBERACIÓN DE PÁGINAS
Asignar bloques de páginas tiende a fragmentar la
memoria al dividir los bloques grandes para conseguir bloques
más pequeños. El código de liberación
de páginas recombina páginas en bloques de mayor
tamaño siempre que es posible. De hecho, el tamaño
de bloque de página es importante pues facilita la
recombinación en bloques grandes.
Siempre que se libera un bloque de páginas, se
comprueba si está libre el bloque adyacente de igual
tamaño. Si es así, se combina con el bloque de
páginas recién liberado para formar un bloque nuevo
de tamaño doble. Cada vez que dos bloques de
páginas se recombinan en uno mayor, el algoritmo de
liberación intenta volver a recombinarlo en otro
aún mayor. De esta forma, los bloques de páginas
libres son tan grandes como la utilización de la memoria
permita.
LA
CACHE DE PÁGINAS LINUX
El cometido de la cache de páginas en Linux es el
de acelerar el acceso a los ficheros de disco. Las lecturas sobre
los ficheros proyectados en memoria se realizan página a
página y estas páginas se guardan en la cache de
páginas.
Siempre que se lee en una página de un fichero
proyectado en memoria, por ejemplo cuando se necesita traer a
memoria una página desde un fichero de intercambio, la
página se lee a través de la cache de
páginas. Linux asigna una página física y lee la
página desde el fichero del disco.
Si es posible, Linux comenzará una lectura de la
siguiente página del fichero. Con esta página de
adelanto se consigue que si el proceso está accediendo las
páginas de forma secuencial, la siguiente página
esté lista y esperando en memoria la petición del
proceso.
Con el tiempo, la cache de páginas va creciendo
conforme las imágenes se leen y ejecutan. Las
páginas han de ser eliminadas de la cache cuando dejan de
utilizarse. Conforme Linux utiliza memoria puede comenzar a
escasear las páginas de memoria física. En esta
situación Linux reducirá el tamaño de la
cache de páginas.
INTERCAMBIANDO Y LIBERANDO PÁGINAS EN
LINUX
Cuando queda poca memoria física, el subsistema
de gestión de memoria de Linux tiene que intentar liberar
páginas físicas. Este trabajo es
realizado por el demonio de intercambio del núcleo
(kswapd). El demonio de intercambio del núcleo es
un tipo especial de proceso, un hilo de ejecución del
núcleo (kernel thread). Los hilos del núcleo son
procesos que
no tienen memoria virtual, en lugar de ello, se ejecutan en modo
núcleo en el espacio de memoria física. Su misión es
la de garantizar que haya suficientes páginas libres en el
sistema para mantener al sistema de gestión de memoria
funcionando eficientemente.
Linux no quiere enviar a disco de intercambio demasiadas
páginas a la vez, por lo lleva la cuenta de cuantas
páginas están en ese momento siendo copiadas al
fichero de intercambio.
Si hay suficientes páginas libres, el demonio de
intercambio se duerme hasta que el temporizador expire, en caso
contrario, el demonio intenta de tres formas distintas reducir el
número de páginas físicas
ocupadas:
- Reduciendo el tamaño de la cache de
páginas y el buffer cache, - Enviando a disco páginas
compartidas, - Enviando a disco o descartando
páginas.
Si el número de páginas libres ha
caído demasiado, el demonio de intercambio
intentará liberar 6 páginas antes de su
próxima ejecución. En caso contrario,
intentará liberar 3 páginas. Los métodos
anteriores se intentan uno tras otro de hasta que se consiguen
liberar suficientes páginas. Luego el demonio de
intercambio se suspende hasta que el temporizador vuelva a
expirar. El demonio recuerda cuál fue el último
método que
empleó para liberar páginas, y la próxima
vez que se ejecuta lo vuelve a intentar con el mismo
método que tuvo éxito.
INTERCAMBIO DE PÁGINAS COMPARTIDAS EN
LINUX
El esquema de compartición de memoria es un
mecanismo de comunicación entre procesos que permite que
dos procesos compartan un espacio de memoria virtual para
intercambiarse información entre ellos.
El demonio de intercambio del núcleo
también utiliza el algoritmo del reloj para intercambiar
las páginas compartidas. Cada vez que se ejecuta, recuerda
cuál fue la última página de memoria virtual
compartida que intercambió. De esta forma se asegura que
todas las áreas de memoria compartida tienen la misma
probabilidad
de ser intercambiadas.
INTERCAMBIANDO Y DESCARTANDO
PÁGINAS
El demonio de swap revisa de uno en uno cada proceso del
sistema para ver si es un buen candidato para intercambiar
algunas de sus páginas. Buenos candidatos son procesos que
pueden ser intercambiados (algunos procesos no pueden, p.e. los
procesos de tiempo real) y que tienen una o más
páginas que pueden ser enviadas al disco o descartadas de
memoria. Las páginas son enviadas al disco sólo si
los datos que contienen no pueden ser recuperados de otra
forma.
Una gran cantidad del contenido de una imagen ejecutable
viene de la imagen del fichero y puede ser fácilmente
releído desde el mismo fichero. Estas páginas
sencillamente se pueden descartar; cuando vuelven a referenciarse
por el proceso, éstas se traen otra vez a memoria desde la
imagen ejecutable del fichero.
Una vez se ha localizado un proceso candidato para
enviar a disco algunas de sus páginas, el demonio de
intercambio examina todas sus regiones de memoria virtual
buscando áreas que no estén compartidas ni
bloqueadas. Linux no intercambiará a disco todas las
páginas posibles del proceso que ha sido elegido;
sólo quitará un pequeño número de
páginas. Las páginas bloqueadas en memoria no se
pueden intercambiar ni descartar.
El algoritmo de intercambio de Linux emplea la
antigüedad de las páginas. Cada página tiene
un contador que da al demonio de intercambio una cierta idea de
si vale la pena o no intercambiar un página. Las
páginas envejecen cuando no son utilizadas y rejuvenecen
cuando son accedidas; el demonio de intercambio sólo
envía a disco páginas viejas. La acción
por defecto cuando se asigna una página por primera vez es
darle un valor inicial
de antigüedad de 3. Cada vez que se accede, el valor de
antigüedad se incrementa en 3 hasta un máximo de
20.
Cada vez que el demonio intercambio se ejecuta, envejece
las páginas decrementando su valor en 1. Si una
página es vieja (age = 0), el demonio de intercambio la
procesará. Páginas sucias (Dirty) son
páginas que se pueden intercambiar.
LA CACHE DE INTERCAMBIO DE
LINUX
Cuando se tiene que intercambiar páginas a disco,
Linux intenta evitar escribirlas. Hay veces que una página
está a en un fichero de intercambio y en memoria
física. Esto sucede cuando una página que fue
intercambiada a disco ha sido nuevamente leída a memoria
principal cuando un proceso la ha necesitado. Mientras la
página que está en memoria no sea modificada por el
proceso, la página que está en disco es
válida.
Linux utiliza la cache de intercambio para gestionar
estas páginas. La cache de intercambio es una lista de
entradas de tabla de páginas, una por cada página
física del sistema. Si una entrada en la cache de
intercambio es distinta de cero, entonces representa una
página que está en el fichero de intercambio que no
ha sido modificada. Si la página se modifica
posteriormente (un proceso escribe sobre ella), su entrada se
borra de la cache de intercambio.
Cuando Linux necesita enviar una página
física a un fichero de intercambio consulta la cache de
intercambio, si hay una entrada válida para está
página, entonces no es necesario copiar la página
al fichero de intercambio. Pues la página de memoria no ha
sido modificada desde la última vez que se leyó del
fichero de intercambio.
Las entradas en la cache de intercambio son entradas de
la tabla de páginas de páginas que estén en
algún fichero de intercambio. Están marcadas como
inválidas pero contienen información que permiten a
Linux encontrar el fichero de intercambio y el página
correcta dentro del fichero de intercambio.
COPY ON
WRITE
Copy-on-write es una técnica para realizar
eficientemente (tanto en tiempo como en memoria) la copia de
páginas. Linux no duplica las páginas de memoria
que son necesarias para un nuevo proceso, sino que hace apuntar
las entradas de la tabla de páginas del nuevo proceso a
las páginas del proceso padre. Cuando alguna de las
páginas es modificada por alguno de los procesos, entonces
el núcleo pasa a realizar la duplicación de dicha
página. Así, Linux se evita la copia de
páginas de memoria que no van ha ser utilizadas ahorrando
la memoria correspondiente y el tiempo necesario para
copiarlas.
La forma de llevar a cabo este proceso consiste en
establecer los permisos de estas páginas a
sólo-lectura pero sabiendo que dichas páginas se
pueden modificar. Cuando ocurre una violación de acceso a
estas páginas (uno de los procesos intenta escribir) es
cuando se realiza la duplicación propiamente
dicha.
AUTOR
Leonardo Muro García
Universidad Nueva Esparta
Facultad de Ciencias
Caracas, Venezuela
21 de Noviembre de 2007
Página anterior | Volver al principio del trabajo | Página siguiente |